package conservare.web.converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;

import org.omnifaces.util.Faces;
import org.omnifaces.util.Messages;

@FacesConverter(value = "omnifaces.GenericEnumConverter")
public class GenericEnumConverter implements Converter{

	 // Constants ------------------------------------------------------------------------------------------------------

    private static final String ATTRIBUTE_ENUM_TYPE = "GenericEnumConverter.%s";
    private static final String ERROR_NO_ENUM_TYPE = "Given type '%s' is not an enum.";
    private static final String ERROR_NO_ENUM_VALUE = "Given value '%s' is not an enum of type '%s'.";

    // Actions --------------------------------------------------------------------------------------------------------

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
            if (modelValue == null) {
                    return null;
            }
            else if (modelValue instanceof Enum) {
                    Faces.setViewAttribute(String.format(ATTRIBUTE_ENUM_TYPE, component.getId()), modelValue.getClass());
                    return ((Enum<?>) modelValue).name();
            }
            else {
                    throw new ConverterException(Messages.createError(ERROR_NO_ENUM_TYPE, modelValue.getClass()));
            }
    }

    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
            if (submittedValue == null) {
                    return null;
            }

            Class<Enum> enumType = Faces.getViewAttribute(String.format(ATTRIBUTE_ENUM_TYPE, component.getId()));

            try {
                    return Enum.valueOf(enumType, submittedValue);
            }
            catch (IllegalArgumentException e) {
                    throw new ConverterException(Messages.createError(ERROR_NO_ENUM_VALUE, enumType));
            }
    }
}
